home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / prospero / propsero.lha / prospero-beta.4.2e / user / archie.c < prev    next >
C/C++ Source or Header  |  1992-02-10  |  10KB  |  352 lines

  1. /*
  2.  * Copyright (c) 1991 by the University of Washington
  3.  *
  4.  * For copying and distribution information, please see the file
  5.  * <uw-copyright.h>.
  6.  *
  7.  * Written by Clifford Neuman (bcn@isi.edu) with changes by
  8.  *            Brendan Kehoe (brendan@cs.widener.edu) and
  9.  *            George Ferguson (ferguson@cs.rochester.edu).
  10.  */
  11.  
  12. #include <uw-copyright.h>
  13.  
  14. #include <stdio.h>
  15. #include <sys/time.h>
  16.  
  17. #include <pfs.h>
  18. #include <perrno.h>
  19. #include <rdgram.h>
  20. #include <archie.h>
  21.  
  22. char            *month_sname();
  23. char            *index();
  24. long             time();
  25.  
  26. void            display_link();
  27.  
  28. int            pfs_debug = 0;
  29. int            perrno;
  30. int            pwarn;
  31.  
  32. /*
  33.  * Archie client using the Prospero protocol
  34.  *
  35.  *  archie [-[cers][l][t][N #][m #][h host]] search-string
  36.  *
  37.  *        Send a query to Prospero server on host running 
  38.  *        Archie, collect, process, and display results.
  39.  *
  40.  *        OPTIONS:
  41.  *          -c : case sensitive substring search
  42.  *           -e : exact string match (default)
  43.  *           -r : regular expression search
  44.  *           -s : case insensitive substring search
  45.  *           -l : list one match per line
  46.  *           -t : sort inverted by date
  47.  *  -N# or -N # : specifies query niceness level (# optional 0-35765)
  48.  *  -m# or -m # : specifies maximum number of hits to return 
  49.  *      -h host : specifies server host
  50.  *
  51.  *  -D# or -D # : Debug level (# optional)
  52.  *
  53.  *                If -e is specified in addition to either -r, -s, or -c, 
  54.  *                then server will try an exact match before falling back
  55.  *                to a more expensive method.
  56.  */
  57. main(argc,argv)
  58.     int        argc;
  59.     char    *argv[];
  60.     {
  61.     char    *cur_arg;             /* For argument parsing           */
  62.     char    *progname = argv[0];
  63.  
  64.     VLINK    results;              /* List of matched links          */
  65.     VLINK    l;                    /* Temporary link pointer         */
  66.  
  67.     char    qtype = '=';          /* Default to exact string match  */
  68.     char    etype = '=';          /* Type if only -e is specified   */
  69.     int     eflag = 0;          /* Exact flag specified           */
  70.     int    max_hits = MAX_HITS;  /* Number of links to be returned */
  71.     int    offset = 0;           /* Skiping over this many         */
  72.     int    listflag = 0;         /* List one match per line        */
  73.     int     (*cmp_proc)();        /* Sort method                    */
  74.     int    versionflag = 0;      /* Display release identifier     */
  75.     char    *host = ARCHIE_HOST;  /* Host to send query             */
  76.     int    tmp;
  77.  
  78.     cmp_proc = AQ_DEFCMP;          /* Default sorting method         */
  79.  
  80.     argc--;argv++;
  81.  
  82.     while (argc > 0 && **argv == '-') {
  83.         cur_arg = argv[0]+1;
  84.  
  85.         /* If a - by itself, or --, then no more arguments */
  86.         if(!*cur_arg || ((*cur_arg == '-') && (!*(cur_arg+1)))) {
  87.         argc--, argv++;
  88.         goto scandone;
  89.         }
  90.         
  91.         while (*cur_arg) {
  92.         switch (*cur_arg++) {
  93.         
  94.         case 'D':  /* debug level */
  95.             pfs_debug = 1; /* Default debug level */
  96.             if(*cur_arg && index("0123456789",*cur_arg)) {
  97.             sscanf(cur_arg,"%d",&pfs_debug);
  98.             cur_arg += strspn(cur_arg,"0123456789");
  99.             }
  100.             else if(argc > 2) {
  101.                 tmp = sscanf(argv[1],"%d",&pfs_debug);
  102.             if (tmp == 1) {argc--;argv++;}
  103.             }
  104.             break;
  105.  
  106.         case 'N':  /* priority (nice) */
  107.             rdgram_priority = RDGRAM_MAX_PRI; /* Use this if no # */
  108.             if(*cur_arg && index("-0123456789",*cur_arg)) {
  109.             sscanf(cur_arg,"%d",&rdgram_priority);
  110.             cur_arg += strspn(cur_arg,"-0123456789");
  111.             }
  112.             else if(argc > 2) {
  113.                 tmp = sscanf(argv[1],"%d",&rdgram_priority);
  114.             if (tmp == 1) {argc--;argv++;}
  115.             }
  116.             if(rdgram_priority > RDGRAM_MAX_SPRI) 
  117.             rdgram_priority = RDGRAM_MAX_PRI;
  118.             if(rdgram_priority < RDGRAM_MIN_PRI) 
  119.             rdgram_priority = RDGRAM_MIN_PRI;
  120.             break;
  121.  
  122.         case 'c':  /* substring (case sensitive) */
  123.             qtype = 'C';
  124.             etype = 'c';
  125.             break;
  126.  
  127.         case 'e':  /* exact match */
  128.             /* If -e specified by itself, then we use the  */
  129.             /* default value of etype which is must be '=' */
  130.             eflag++;
  131.             break;
  132.  
  133.         case 'h':  /* host */
  134.             host = argv[1];
  135.             argc--;argv++;
  136.             break;
  137.  
  138.         case 'l':  /* list one match per line */
  139.             listflag++;
  140.             break;
  141.  
  142.         case '0': case '1': case '2': case '3': case '4':
  143.         case '5': case '6': case '7': case '8': case '9':
  144.             cur_arg--;
  145.         case 'm':  /* max hits */
  146.             max_hits = -1;  
  147.             if(*cur_arg && index("0123456789",*cur_arg)) {
  148.             sscanf(cur_arg,"%d",&max_hits);
  149.             cur_arg += strspn(cur_arg,"0123456789");
  150.             }
  151.             else if(argc > 1) {
  152.                 tmp = sscanf(argv[1],"%d",&max_hits);
  153.             if(tmp == 1) {argc--;argv++;}
  154.             }
  155.             if(max_hits < 1) {
  156.             fprintf(stderr, "%s: -m option requires a value for max hits (>= 1)\n",
  157.                 progname);
  158.             exit(1);
  159.             }
  160.             break;
  161.  
  162.         case 'o':  /* offset */
  163.             if(*cur_arg && index("0123456789",*cur_arg)) {
  164.             sscanf(cur_arg,"%d",&offset);
  165.             cur_arg += strspn(cur_arg,"0123456789");
  166.             }
  167.             else if(argc > 1) {
  168.                 tmp = sscanf(argv[1],"%d",&offset);
  169.             if(tmp == 1) {argc--;argv++;}
  170.             }
  171.             if(offset < 0) {
  172.             fprintf(stderr, "%s: -o option requires a value for offset (>= 0)\n",
  173.                 progname);
  174.             exit(1);
  175.             }
  176.             break;
  177.  
  178.         case 'r':  /* regular expression search */
  179.             qtype = 'R';
  180.             etype = 'r';
  181.             break;
  182.  
  183.         case 's':  /* substring (case insensitive) */
  184.             qtype = 'S';
  185.             etype = 's';
  186.             break;
  187.  
  188.         case 't':  /* sort inverted by date */
  189.             cmp_proc = AQ_INVDATECMP;
  190.             break;
  191.  
  192.         case 'v':  /* display version */
  193.             fprintf(stderr,"Prospero client - Version %s\n",
  194.                 PFS_RELEASE);
  195.             versionflag++;
  196.             break;
  197.  
  198.         default:
  199.             fprintf(stderr,"Usage: %s [-[cers][l][t][N #][m #][h host]] search-string\n", progname);
  200.             exit(1);
  201.         }
  202.         }
  203.         argc--, argv++;
  204.     }
  205.  
  206.     scandone:
  207.  
  208.     /* If -e specified, then choose the exact version of -crs option */
  209.     if(eflag) qtype = etype;
  210.  
  211.     /* If only -v specified, return, but not an error */
  212.     if((argc != 1) && versionflag) exit(0);
  213.  
  214.     if(argc != 1) {
  215.         fprintf(stderr,"Usage: %s [-[cers][l][t][N #][m #][h host]] search-string\n", progname);
  216.         fprintf(stderr,"       -c : case sensitive substring search\n");
  217.         fprintf(stderr,"       -e : exact string match (default)\n");
  218.         fprintf(stderr,"       -r : regular expression search\n");
  219.         fprintf(stderr,"       -s : case insensitive substring search\n");
  220.         fprintf(stderr,"       -l : list one match per line\n");
  221.         fprintf(stderr,"       -t : sort inverted by date\n");
  222.         fprintf(stderr,"     -N # : specifies query niceness level (optional 0-35765)\n");
  223.         fprintf(stderr,"     -m # : specifies maximum number of hits to return\n");
  224.         fprintf(stderr,"  -h host : specifies server host\n");
  225.         exit(1);
  226.     }
  227.  
  228.     perrno = 0; *p_err_string = '\0';
  229.     pwarn = 0;  *p_warn_string = '\0';
  230.  
  231.     results = archie_query(host,argv[0],max_hits,offset,qtype,cmp_proc,0);
  232.  
  233.     if(!results && perrno) {
  234.         fprintf(stderr,"%s",progname);
  235.         perrmesg(" failed: ",0,NULL);
  236.         exit(1);
  237.     }
  238.  
  239.     if(pwarn) pwarnmesg("WARNING: ",0,NULL);
  240.  
  241.     /* Display the results */
  242.     for(l = results; l; l = l->next) display_link(l,listflag);
  243.  
  244.     if(!listflag) printf("\n");
  245.  
  246.     vllfree(l);
  247.     exit(0);
  248.     }
  249.  
  250. /*
  251.  * display_link: Prints the value of a virtual link. If listflag is 0, 
  252.  *               then the link is displayed in a format suitable for
  253.  *               reading by humans.  If listflag is non-zero all 
  254.  *               information is printed on a single line in a form
  255.  *               suitable for parsing by programs.
  256.  *
  257.  *         NOTE: If listflag is zero, this procedure uses static variables
  258.  *               to detect when fields have changed since the last call.
  259.  *               The display of field unchanged since the last call is
  260.  *               suppressed.
  261.  */
  262. void
  263. display_link(l,listflag)
  264.     VLINK l;        /* Link to be displayed               */
  265.     int listflag;   /* non-zero = List one match per line */
  266.     {
  267.     static char     lastpath[MAX_VPATH] = "\001";
  268.     static char     lasthost[MAX_VPATH] = "\001";
  269.     
  270.     static struct tm *presenttime = NULL;
  271.     long         now;
  272.  
  273.     char         linkpath[MAX_VPATH];
  274.     char         archie_date[20];
  275.     int         dirflag = 0;
  276.     int         size = 0;
  277.     char         *modes = "";
  278.     char         *gt_date = "";
  279.     int         gt_year = 0;
  280.     int         gt_mon = 0;
  281.     int         gt_day = 0;
  282.     int         gt_hour = 0;
  283.     int         gt_min = 0;
  284.     PATTRIB      ap;
  285.  
  286.     
  287.     /* First time called, set localtime */
  288.     if(!presenttime) {
  289.         (void) time(&now);
  290.         presenttime = localtime(&now);
  291.     }
  292.  
  293.     /* Initialize local buffers */
  294.     *archie_date = '\0';
  295.  
  296.     /* Remember if we're looking at a directory */
  297.     if (sindex(l->type,"DIRECTORY")) dirflag = 1;
  298.     else dirflag = 0;
  299.     
  300.     /* Extract the linkpath from the filename */
  301.     strcpy(linkpath,l->filename);
  302.     *(linkpath + (strlen(linkpath) - strlen(l->name) - 1)) = '\0';
  303.     
  304.     /* Is this a new host? */
  305.     if (strcmp(l->host,lasthost) != 0) {
  306.         if (!listflag)
  307.         printf("\nHost %s\n\n",l->host);
  308.         strcpy(lasthost,l->host);
  309.         *lastpath = '\001';
  310.     }
  311.     
  312.     /* Is this a new linkpath (location)? */
  313.     if(strcmp(linkpath,lastpath) != 0) {
  314.         if (!listflag)
  315.         printf("    Location: %s\n",(*linkpath ? linkpath : "/"));
  316.         strcpy(lastpath,linkpath);
  317.     }
  318.     
  319.     /* Parse the attibutes of this link */
  320.     for (ap = l->lattrib; ap; ap = ap->next) {
  321.         if (strcmp(ap->aname,"SIZE") == 0) {
  322.         sscanf(ap->value.ascii,"%d",&size);
  323.         } else if(strcmp(ap->aname,"UNIX-MODES") == 0) {
  324.         modes = ap->value.ascii;
  325.         } else if(strcmp(ap->aname,"LAST-MODIFIED") == 0) {
  326.         gt_date = ap->value.ascii;
  327.         sscanf(gt_date,"%4d%2d%2d%2d%2d",>_year,
  328.                >_mon, >_day, >_hour, >_min);
  329.         if ((12 * (presenttime->tm_year + 1900 - gt_year) + 
  330.              presenttime->tm_mon - gt_mon) > 6) 
  331.             sprintf(archie_date,"%s %2d %4d",month_sname(gt_mon),
  332.                 gt_day, gt_year);
  333.         else
  334.             sprintf(archie_date,"%s %2d %02d:%02d",month_sname(gt_mon),
  335.                 gt_day, gt_hour, gt_min);
  336.         }
  337.     }
  338.     
  339.     /* Print this link's information */
  340.     if (listflag)
  341.         printf("%s %6d %s %s%s\n",gt_date,size,l->host,l->filename,
  342.            (dirflag ? "/" : ""));
  343.     else
  344.         printf("      %9s %s %10d  %s  %s\n",(dirflag ? "DIRECTORY" : "FILE"),
  345.            modes,size,archie_date,l->name);
  346.     
  347.     /* Free the attibutes */
  348.     atlfree(l->lattrib);
  349.     l->lattrib = NULL;
  350.     }
  351.     
  352.